/*
 * easysmtp - A simple C lib in Linux to help you send mails in an easy way 
 * Copyright (C) 2012-2013, easysmtp developers and contributors
 *
 * easysmtp is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * easysmtp is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with easysmtp; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "ssl.h"

//采用ssl连接
int 
send_ssl_mail(SMTP *smtpr, MAIL *mpr) 
{
	SSL_METHOD *method;		
	SSL_CTX *ctx;
	int return_num;
	
	//openssl库初始化，初始后才可以用
	SSL_library_init();
	//错误信息相关的初始化
	SSL_load_error_strings();
	smtpr->ssl_flag = 1;

	//创建一个上下文结构
	method = (SSL_METHOD *)SSLv23_method();	
	if((ctx = SSL_CTX_new(method)) == NULL) {
		return SSL_ERROR;
	}

	//证书的口令
	SSL_CTX_set_default_passwd_cb_userdata(ctx, "passwd");
	if(SSL_CTX_load_verify_locations(ctx, "ca.crt", NULL) == 0) {
		return SSL_ERROR;
	}
	//加载证书
	if(!SSL_CTX_use_certificate_chain_file(ctx, CERTF)) {
		return SSL_ERROR;
	}
	//加载私钥
	if(!SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM)) {
		return SSL_ERROR;
	}
	//加载CA
	if(!SSL_CTX_check_private_key(ctx)) {
		return SSL_ERROR;
	}

	//建立套接字
	struct sockaddr_in *server = (struct sockaddr_in *)
				malloc(sizeof(struct sockaddr_in *));
	pre_connect(smtpr, server, SSLPORT);
	struct sockaddr_in sv = *server;

	//创建一个ssl对象
	if((smtpr->ssl = SSL_new(ctx)) == NULL) {
		return SSL_ERROR;
	}
	if(-1 == connect(smtpr->sockfd, (struct sockaddr *)&sv, 
			sizeof(sv))) {
		return SYS_ERROR;
	}

	if(!SSL_set_fd(smtpr->ssl, smtpr->sockfd)) {
		return SSL_ERROR;
	}
	if(SSL_connect(smtpr->ssl) != 1) {
		return SSL_ERROR;
	}
	return_num = read_msg(smtpr);
	if(return_num != SMTP_SUCCESS) {
		return return_num;
	}
	return exec_process(smtpr, mpr);
}
